package org.budo.graph.metric;

import lombok.extern.slf4j.Slf4j;
import org.budo.support.lang.util.UuidUtil;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Supplier;

/**
 * @author lmw
 */
@Slf4j
public class MetricUtil {
    private static final Map<String, Metric> _METRIC_MAP = new ConcurrentHashMap<String, Metric>();

    public static String before(String key, Boolean graph) {
        Metric metric = _METRIC_MAP.get(key);

        if (null == metric) {
            synchronized (MetricUtil.class) {
                metric = _METRIC_MAP.get(key);

                if (null == metric) {
                    _METRIC_MAP.put(key, metric = new Metric(key, graph));
                }
            }
        }

        String uuid = UuidUtil.randomUuid();
        metric.before(uuid);
        return uuid;
    }

    public static String before(String key) {
        return before(key, false);
    }

    public static void after(String key, String uuid) {
        Metric metric = _METRIC_MAP.get(key);
        if (null == metric) {
            log.error("#28 no Metric by key = " + key);
            return;
        }

        metric.after(uuid);
    }

    // 执行中
    // 最大并发
    public static Map<String, Metric> metricMap() {
        return _METRIC_MAP;
    }

    public static void wrap(String metricKey, Runnable runnable) {
        String uuid = MetricUtil.before(metricKey, true);
        runnable.run();
        MetricUtil.after(metricKey, uuid);
    }

    public static <T> T wrap(String metricKey, Supplier<T> supplier) {
        String uuid = MetricUtil.before(metricKey, true);
        T t = supplier.get();
        MetricUtil.after(metricKey, uuid);
        return t;
    }
}
